package rabbitmq.test;

import com.rabbitmq.client.*;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * rabbitmq组件 exchange交换机 有默认的7个 queue默认空的
 * 所以如果希望使用这个中间件,第一件事就是使用开发语言客户端代码
 * 连接rabbitmq实现组件声明(创建)
 */
public class Declare {
    //每一个测试类都准备一个连接对象
    private Channel channel;
    @Before
    public void init(){
        //1.创建长连接 提供属性(ip,port,username,password,virtualHost)
        ConnectionFactory factory=new ConnectionFactory();
        factory.setHost("192.168.8.100");
        factory.setPort(5672);//TCP协议端口
        factory.setUsername("admin");
        factory.setPassword("123456");
        factory.setVirtualHost("/");
        try{
            Connection connection = factory.newConnection();
            //2.从长连接赋值短链接
            channel=connection.createChannel();
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("创建连接失败");
        }
    }
    @Test
    public void queueDeclare() throws IOException {
        //声明组件包括 交换机和队列
        /**
         * 参数详解
         * String queue: 创建的队列名称,在虚拟主机中 只能存在唯一名称
         * Boolean durable: 队列是否持久化 true在rabbitmq重启之后 队列保持存在 false不存在
         * Boolean exclusive: 队列是绑定当前连接对象(独占 专属) true别的链接无法操作队列 false所有连接都可以操作队列
         * Boolean autoDelete: 队列是否自动删除 true队列从第一个监听消费者开始计算,到最后一个消费者断开连接,自动删除 false不删除
         * Map<String,Object> args: 队列特性参数,key值是rabbitmq固定的,比如
         * "x-expires" 1000S 队列过期时间 当队列没有产生消息,没有消费监听 最长等待时间1000s
         */
        Map<String,Object> args=new HashMap<>();
        args.put("name","王翠花");
        channel.queueDeclare(
                "queue01",
                true,
                false,
                false,
                args);
    }

    //声明一个交换机 和2个队列 已经确认绑定关系
    @Test
    public void declareDirect() throws IOException {
        channel.queueDeclare("ex_queue01", true, false, false, null);
        channel.queueDeclare("ex_queue02", true, false, false, null);
        //声明交换机
        /**
         * String exchange: 交换机名称
         * String type: 交换机类型 direct fanout topic headers
         * Boolean durable: 交换机是否持久化 如果true 关闭rabbitmq 重启 交换机依然存在
         * Boolean autoDelete: 交换机是否自动删除 如果true 有至少一个交换机或者队列绑定这个交换机之后,直到所有的绑定都解除,自动删除
         * Map<String,Object> arguments: 其他属性,比如是否是直接还是间接交换机
         */
        channel.exchangeDeclare("direct_ex","direct",true,false,null);
        //自定义队列和交换机的绑定关系 北京 上海
        channel.queueBind("ex_queue01","direct_ex","北京");
        channel.queueBind("ex_queue02","direct_ex","上海");
        //同一个队列和交换机可以存在多个绑定关系
        channel.queueBind("ex_queue01","direct_ex","哈尔滨");
    }

    @Test
    public void declareFanout() throws IOException {
        channel.queueDeclare("ex_queue03", true, false, false, null);
        channel.queueDeclare("ex_queue04", true, false, false, null);
        //声明交换机
        /**
         * String exchange: 交换机名称
         * String type: 交换机类型 direct fanout topic headers
         * Boolean durable: 交换机是否持久化 如果true 关闭rabbitmq 重启 交换机依然存在
         * Boolean autoDelete: 交换机是否自动删除 如果true 有至少一个交换机或者队列绑定这个交换机之后,直到所有的绑定都解除,自动删除
         * Map<String,Object> arguments: 其他属性,比如是否是直接还是间接交换机
         */
        channel.exchangeDeclare("fanout_ex","fanout",true,false,null);
        //自定义队列和交换机的绑定关系 北京 上海
        channel.queueBind("ex_queue03","fanout_ex","北京");
        //同一个队列和交换机可以存在多个绑定关系
        channel.queueBind("ex_queue04","fanout_ex","哈尔滨");
    }

    @Test
    public void declareTopic() throws IOException {
        channel.queueDeclare("ex_queue05", true, false, false, null);
        channel.queueDeclare("ex_queue06", true, false, false, null);
        //声明交换机
        /**
         * String exchange: 交换机名称
         * String type: 交换机类型 direct fanout topic headers
         * Boolean durable: 交换机是否持久化 如果true 关闭rabbitmq 重启 交换机依然存在
         * Boolean autoDelete: 交换机是否自动删除 如果true 有至少一个交换机或者队列绑定这个交换机之后,直到所有的绑定都解除,自动删除
         * Map<String,Object> arguments: 其他属性,比如是否是直接还是间接交换机
         */
        channel.exchangeDeclare("topic_ex","topic",true,false,null);
        //自定义队列和交换机的绑定关系 北京 上海
        channel.queueBind("ex_queue05","topic_ex","北京");
        //同一个队列和交换机可以存在多个绑定关系
        channel.queueBind("ex_queue06","topic_ex","中国.#");
    }
    //声明一个有超时时间的队列 最大空闲时长20秒
    @Test
    public void queueExpireDeclare() throws IOException {
        Map<String,Object> args=new HashMap<>();
        //x-expire 20000
        args.put("x-expires",20000);
        channel.queueDeclare("queue01", false, false, false, args);
    }
}

